@秒灵儿
2年前 提问
1个回答

防止缓冲区溢出攻击的方法有什么

房乐
2年前
官方采纳

目前有以下几种基本的方法保护缓冲区免受缓冲区溢出的攻击和影响:1.

  • 编写正确的代码:编写正确的代码是防止缓冲区溢出攻击最直接最有效的方法,也是一件非常有意义的工作,特别是编写像C语言那种具有容易出错倾向的程序更显得很有意义。然而,尽管花了很长的时间使得人们知道了如何编写安全的程序组,但是具有安全漏洞的程序依旧出现。为此,人们又开发了一些工具和技术来帮助经验不足的程序员编写安全正确的程序代码。最简单的方法就是用grep来搜索源代码中容易产生漏洞的库的调用,然而依然有漏网之鱼存在。为了应对这些问题,人们又开发了一些高级的查错工具,如faultinjection等。这些工具的目的在于通过人为随机地产生一些缓冲区溢出来寻找代码的安全漏洞,还有一些静态分析工具,用于侦测缓冲区溢出的存在。

  • 非执行的缓冲区:通过使被攻击程序的数据段地址空间不可执行,从而使得攻击者不可能执行被植入被攻击程序输入缓冲区的代码,这种技术被称为非执行的缓冲区技术。事实上,很多旧的UNIX系统都是这样设计的,但是近来的UNIX和Windows系统为实现更好的性能和功能,往往在数据段中动态地放入可执行的代码,所以,为了保持程序的兼容性,不可能使得所有程序的数据段不可执行。针对这一问题,用户可以设定堆栈数据段不可执行,这样就可以最大限度地保证了程序的兼容性。Linux和Windows都发布了有关这方面的内核补丁,因为几乎没有任何合法的程序会在堆栈中存放代码,这种做法几乎不产生任何兼容性问题,但是在Linux中的两个特例中,可执行的代码必须被放入堆栈中,因此这个方法虽好,但还是不能完全地杜绝所有的缓冲区溢出漏洞的攻击。

  • 数组边界检查:数组边界检查能防止所有的缓冲区溢出的产生和攻击。这是因为只要数组不能被溢出,也就是说,如果数据不允许超过长度,溢出攻击也就无从谈起。为了实现数组边界检查,就需要把所有对数组的读写操作都检查一遍,以确保对数组的操作在正确的范围。最直接的方法是检查所有的数组操作,但是通常可以来用一些优化的技术来减少检查的次数。

  • 程序指针完整性检查:程序指针完整性检查和边界检查有略微的不同。与防止程序指针被改变不同,程序指针完整性检查在程序指针被引用之前检测到它的改变。因此,即便一个攻击者成功地改变程序的指针,由于系统事先检测到了指针的改变,因此这个指针将不会被使用。与数组边界检查相比,这种方法不能解决所有的缓冲区溢出问题;采用其他的缓冲区溢出方法就可以避免这种检测。但是这种方法在性能上有很大的优势,而且兼容性也很好。